const Router = require("koa-router");
const { koaBody } = require("koa-body");
const fs = require("fs");
const path = require("path");

const router = new Router();

// 上传目录
const UPLOAD_DIR = path.join(__dirname, "uploads");
const TEMP_DIR = path.join(UPLOAD_DIR, "temp");
if (!fs.existsSync(UPLOAD_DIR)) fs.mkdirSync(UPLOAD_DIR);
if (!fs.existsSync(TEMP_DIR)) fs.mkdirSync(TEMP_DIR);

// 文件名安全化
function safeName(name) {
  return name.replace(/[ #?&%/:<>*|"\\]/g, "_");
}

// 统一生成 safeBase（保留扩展名）
function getSafeBase(filename, hash) {
  return safeName(filename + "_" + hash);
}

/**
 * 📌 查询已上传分片（断点续传）
 */
router.post("/checkFile", async (ctx) => {
  const { filename, hash } = ctx.request.body;

  if (!filename || !hash) {
    ctx.body = { code: 400, message: "缺少 filename 或 hash" };
    return;
  }

  const safeBase = getSafeBase(filename, hash);
  const tempDir = path.join(TEMP_DIR, safeBase);

  let uploaded = [];
  if (fs.existsSync(tempDir)) {
    uploaded = fs.readdirSync(tempDir)
      .filter(f => !isNaN(Number(f))) // 只保留数字分片
      .map(f => Number(f))
      .sort((a, b) => a - b);
  }

  ctx.body = { code: 200, uploaded };
});

/**
 * 📌 上传单个分片
 */
router.post("/upload-files", koaBody({ multipart: true }), async (ctx) => {
  try {
    const { files, body } = ctx.request;
    const chunk = files?.file;
    let { index, filename, hash } = body;

    if (!chunk) {
      ctx.body = { code: 400, message: "未找到文件" };
      return;
    }

    index = Number(index);
    const safeBase = getSafeBase(filename, hash);
    const fileTempDir = path.join(TEMP_DIR, safeBase);
    if (!fs.existsSync(fileTempDir)) fs.mkdirSync(fileTempDir);

    const chunkPath = path.join(fileTempDir, `${index}`);

    // 保存分片，并确保写入完成
    await new Promise((resolve, reject) => {
      const reader = fs.createReadStream(chunk.filepath);
      const writer = fs.createWriteStream(chunkPath);
      reader.pipe(writer);
      writer.on("finish", resolve);
      writer.on("error", reject);
    });

    ctx.body = { code: 200, message: "分片上传成功" };
  } catch (err) {
    console.error(err);
    ctx.status = 500;
    ctx.body = { code: 500, message: "分片上传失败" };
  }
});

/**
 * 📌 合并分片
 */
router.post("/mergeFile", async (ctx) => {
  try {
    const { filename, hash } = ctx.request.body;

    if (!filename || !hash) {
      ctx.body = { code: 400, message: "缺少 filename 或 hash" };
      return;
    }

    const safeBase = getSafeBase(filename, hash);
    const fileTempDir = path.join(TEMP_DIR, safeBase);
    const finalFilePath = path.join(UPLOAD_DIR, filename);

    if (!fs.existsSync(fileTempDir)) {
      throw new Error("分片目录不存在！");
    }
     console.log("🔧 开始合并分片目录：", fileTempDir);
    // 获取分片并排序
    const chunks = fs.readdirSync(fileTempDir)
      .filter(f => !isNaN(Number(f)))
      .map(f => Number(f))
      .sort((a, b) => a - b);
    console.log("分片排序",chunks)
    const writeStream = fs.createWriteStream(finalFilePath);

    for (let i of chunks) {
      const chunkPath = path.join(fileTempDir, `${i}`);
      console.log("🔨 合并分片: ", chunkPath);
      await new Promise((resolve, reject) => {
        const reader = fs.createReadStream(chunkPath);
        reader.on("data", (data) => writeStream.write(data));
        reader.on("end", resolve);
        reader.on("error", reject);
      });
    }

    writeStream.end();

    // // 删除临时分片
    // fs.rm(fileTempDir, { recursive: true, force: true }, (err) => {
    //   if (err) console.error("删除临时分片失败:", err);
    // });

    ctx.body = {
      code: 200,
      message: "合并成功",
      filePath: finalFilePath
    };

  } catch (err) {
    console.error("合并失败:", err);
    ctx.status = 500;
    ctx.body = { code: 500, message: "合并失败" };
  }
});

module.exports = router;
